package com.hz.foodstalls.weixin.controller;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;
import com.hz.foodstalls.controller.BaseController;
import com.hz.foodstalls.interceptor.WxInterceptor;
import com.hz.foodstalls.model.Reserve;
import com.hz.foodstalls.model.Restaurant;
import com.hz.foodstalls.model.SmsReturn;
import com.hz.foodstalls.model.SmsSend;
import com.hz.foodstalls.model.WechatInfo;
import com.hz.foodstalls.model.WxUser;
import com.hz.foodstalls.util.SmsUtil;
import com.hz.yunpian.model.SendBatchInfo;
import com.jfinal.aop.Before;
import com.jfinal.ext.kit.JsonExtKit;
import com.jfinal.ext.kit.RandomKit;
import com.jfinal.ext.route.ControllerBind;
import com.jfinal.kit.HttpKit;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.jfinal.weixin.sdk.api.ApiConfig;
import com.jfinal.weixin.sdk.api.ApiConfigKit;
import com.jfinal.weixin.sdk.api.PaymentApi;
import com.jfinal.weixin.sdk.api.PaymentApi.TradeType;
import com.jfinal.weixin.sdk.kit.IpKit;
import com.jfinal.weixin.sdk.kit.PaymentKit;
import com.jfinal.weixin.sdk.utils.JsonUtils;

import jodd.util.URLDecoder;

@ControllerBind(controllerKey = "/wxReserve", viewPath = "/WEB-INF/views/weichat/")
public class WxReserveController extends BaseController {

    @Before(WxInterceptor.class)
    public void index() {
        // 获取微信信息
        String openid = getSessionAttr("openid");
        WxUser wxuser = null;
        if (openid != null && !"".equals(openid)) {
            wxuser = WxUser.dao.findByOpenId(openid);
        }
        setSessionAttr("wxuser", wxuser);
        // 定义值 防止数据回显报错
        Reserve model = new Reserve();
        // setAttr("reserve_date", "");
        // setAttr("reserve_time", "");
        setAttr("payflag", "0");
        setAttr("model", model);
        render("reserve.html");
    }

    public void auth() {
        String code = getPara("code");
        ApiConfig conf = ApiConfigKit.getApiConfig(getPara("appId"));
        String json = HttpKit.get("https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + conf.getAppId()
                + "&secret=" + conf.getAppSecret() + "&code=" + code + "&grant_type=authorization_code");

        Map<String, String> map = JsonExtKit.jsonToMap(json);
        String userinfo = HttpKit.get("https://api.weixin.qq.com/sns/userinfo?access_token=" + map.get("access_token")
                + "&openid=" + map.get("openid") + "&lang=zh_CN");
        renderJson(userinfo);
    }

    public void jssdk() {
        setAttr("appId", getPara("appId"));
        renderJsp("/jsp/test.jsp");
    }

    public void succ() {
        render("success.html");
    }

    public void pay() {
        Reserve model = new Reserve();
        Date date = new Date();
        SimpleDateFormat d = new SimpleDateFormat("yyyyMMddHHmmssSSS");
        int r = RandomKit.random(100, 999);// (int) (Math.random() * 900) +
                                           // 100;// 生成100到999的随机整数
        WxUser wxuser = (WxUser) getSessionAttr("wxuser");
        // 获取微信信息
        if (wxuser != null) {
            model.setWxuserId(wxuser.getId());
        } else {
            model.setWxuserId(-1);
        }
        // model.setWxuserId(1);// 测试用
        // 生成订单号
        model.setReserveId(d.format(date).substring(2) + r);
        model.setName(getPara("name"));
        model.setMobile(getPara("mobile"));
        model.setPeoperNum(getParaToInt("people_num"));
        model.setReserveDate(getPara("reserve_date") + " " + getPara("reserve_time"));
        model.setNeedroom(0);
        // if (getPara("needroom") != null && !"".equals(getPara("needroom"))) {
        // model.setNeedroom(1);// 需要包间
        // } else {
        // model.setNeedroom(0);
        // }
        model.setInsertDate(date);
        model.setReservestate(0);// 0为未完成付款状态 1为完成付款未接单 2为接单状态
        if (getPara("remark") != null && !"".equals(getPara("remark"))) {// 备注
            model.setRemerk(getPara("remark"));
        } else {
            model.setRemerk("");
        }
        model.save();
        setAttr("model", model);
        setAttr("reserve_date", getPara("reserve_date"));
        setAttr("reserve_time", getPara("reserve_time"));
        setAttr("payflag", "1");

        // boolean isSave = model.getId() == null;
        // if (Reserve.dao.saveOrUpdate(model, isSave)){
        //
        // }
        String userAgent = getRequest().getHeader("User-Agent");
        String agent = userAgent.toLowerCase();
        if (agent.indexOf("micromessenger") > 0) {
            render("reserve.html");
        } else {
            // 统一下单文档地址：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
            Map<String, String> params = new HashMap<String, String>();
            String appid = PropKit.get("appid");
            String notify_url = PropKit.get("notify_url");
            WechatInfo wi = WechatInfo.dao.getByAppid(appid);
            String partner = String.valueOf(wi.getMchid());
            String paternerKey = wi.getPayKey();
            params.put("appid", appid);
            params.put("mch_id", partner);
            params.put("body", PropKit.get("title"));

            // 商品ID trade_type=NATIVE，此参数必传。此id为二维码中包含的商品ID，商户自行定义。
            params.put("product_id", "1");
            // 商户订单号 商户系统内部的订单号,32个字符内、可包含字母, 其他说明见商户订单号
            params.put("out_trade_no", model.getReserveId());
            params.put("total_fee", PropKit.get("deposit"));

            String ip = IpKit.getRealIp(getRequest());
            if (StrKit.isBlank(ip)) {
                ip = "127.0.0.1";
            }

            params.put("spbill_create_ip", ip);
            params.put("trade_type", TradeType.NATIVE.name());
            params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
            params.put("notify_url", notify_url);

            String sign = PaymentKit.createSign(params, paternerKey);
            params.put("sign", sign);
            String xmlResult = PaymentApi.pushOrder(params);

            System.out.println(xmlResult);
            Map<String, String> result = PaymentKit.xmlToMap(xmlResult);

            String return_code = result.get("return_code");
            String return_msg = result.get("return_msg");
            if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
                renderText(return_msg);
                return;
            }
            String result_code = result.get("result_code");
            if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
                renderText(return_msg);
                return;
            }
            // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
            String prepay_id = result.get("prepay_id");
            // trade_type为NATIVE是有返回，可将该参数值生成二维码展示出来进行扫码支付
            String code_url = result.get("code_url");

            setAttr("code_url", code_url);
            render("pc_pay.html");
        }

    }

    public void wxpay() {
        // openId，采用 网页授权获取 access_token API：SnsAccessTokenApi获取
        String reserve_id = getPara("reserve_id");
        String openId = getSessionAttr("openid");
        // String appid = "wxca429d8a8ab133ca";
        // String partner = "1301035601";
        // String paternerKey = "4v1lzy7l0g95eb3o8z0tb4szl8p08z7c";
        // String notify_url =
        // "http://wxp.tunnel.zshuizhi.cn/wxReserve/pay_notify";
        // ---------------------------------------------------------------
        // String appid = PropKit.get("appid");
        // String partner = PropKit.get("partner");
        // String paternerKey = PropKit.get("paternerKey");
        String appid = getSessionAttr("appid");
        String notify_url = PropKit.get("notify_url");
        WechatInfo wi = WechatInfo.dao.getByAppid(appid);
        String partner = String.valueOf(wi.getMchid());
        String paternerKey = wi.getPayKey();

        // 统一下单文档地址：https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1

        Map<String, String> params = new HashMap<String, String>();
        params.put("appid", appid);
        params.put("mch_id", partner);
        params.put("body", PropKit.get("title"));
        params.put("out_trade_no", reserve_id);
        params.put("total_fee", PropKit.get("deposit"));

        String ip = IpKit.getRealIp(getRequest());
        if (StrKit.isBlank(ip)) {
            ip = "127.0.0.1";
        }

        params.put("spbill_create_ip", ip);
        params.put("trade_type", TradeType.JSAPI.name());
        params.put("nonce_str", System.currentTimeMillis() / 1000 + "");
        params.put("notify_url", notify_url);
        params.put("openid", openId);

        String sign = PaymentKit.createSign(params, paternerKey);
        params.put("sign", sign);
        String xmlResult = PaymentApi.pushOrder(params);

        System.out.println(xmlResult);
        Map<String, String> result = PaymentKit.xmlToMap(xmlResult);

        String return_code = result.get("return_code");
        String return_msg = result.get("return_msg");
        if (StrKit.isBlank(return_code) || !"SUCCESS".equals(return_code)) {
            renderText(return_msg);
            return;
        }
        String result_code = result.get("result_code");
        if (StrKit.isBlank(result_code) || !"SUCCESS".equals(result_code)) {
            renderText(return_msg);
            return;
        }
        // 以下字段在return_code 和result_code都为SUCCESS的时候有返回
        String prepay_id = result.get("prepay_id");

        Map<String, String> packageParams = new HashMap<String, String>();
        packageParams.put("appId", appid);
        packageParams.put("timeStamp", System.currentTimeMillis() / 1000 + "");
        packageParams.put("nonceStr", System.currentTimeMillis() + "");
        packageParams.put("package", "prepay_id=" + prepay_id);
        packageParams.put("signType", "MD5");
        String packageSign = PaymentKit.createSign(packageParams, paternerKey);
        packageParams.put("paySign", packageSign);
        System.out.println(packageParams);

        String jsonStr = JsonUtils.toJson(packageParams);
        System.out.println(jsonStr);
        // setAttr("json", jsonStr);
        // renderJson(jsonStr);
        renderJson(jsonStr);
    }

    /**
     * 支付成功通知
     */
    @Before(Tx.class)
    public void pay_notify() {
        // 支付结果通用通知文档:
        // https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
        // String paternerKey = PropKit.get("paternerKey");
        String tels = "";
        // String appid = getSessionAttr("appid");
        String xmlMsg = HttpKit.readData(getRequest());
        System.out.println("支付通知=" + xmlMsg);
        Map<String, String> params = PaymentKit.xmlToMap(xmlMsg);

        String appid = params.get("appid");
        WechatInfo wi = WechatInfo.dao.getByAppid(appid);
        String paternerKey = wi.getPayKey();

        String result_code = params.get("result_code");
        // 总金额
        String totalFee = params.get("total_fee");
        // 商户订单号
        String orderId = params.get("out_trade_no");
        // 微信支付订单号
        String transId = params.get("transaction_id");
        // 支付完成时间，格式为yyyyMMddHHmmss
        String timeEnd = params.get("time_end");
        if (PaymentKit.verifyNotify(params, paternerKey)) {
            if (("SUCCESS").equals(result_code)) {
                // 注意重复通知的情况，同一订单号可能收到多次通知，请注意一定先判断订单状态
                // 避免已经成功、关闭、退款的订单被再次更新
                Reserve reserve = Reserve.dao.findByReserveId(orderId);
                if (reserve.getReservestate() == 0) {
                    // 更新订单信息
                    System.out.println("更新订单信息");
                    reserve.setReservestate(1);
                    reserve.setTotalFee(totalFee);
                    reserve.setTimeEnd(timeEnd);
                    reserve.setTransId(transId);
                    reserve.update();

                    String text = "【沈家门海鲜夜排档】订单来了,人数:" + reserve.getPeoperNum() + ",时间:" + reserve.getReserveDate()
                            + ",回复" + reserve.getReserveId().substring(4) + "抢单!";
                    System.out.println(text);
                    List<Restaurant> list = Restaurant.dao.findAll();
                    if (list != null && !"".equals(list)) {
                        for (Restaurant r : list) {
                            if (r.getPhone() != null && !"".equals(r.getPhone())) {
                                tels = tels + r.getPhone() + ",";
                            }
                        }
                    }
                    if (!"".equals(tels)) {
                        tels = tels.substring(0, tels.length() - 1);
                    }
                    // 发送短信
                    SendBatchInfo batchinfo = SmsUtil.smsSend(tels, text);
                    int total_count = batchinfo.getTotal_count();
                    // 将短信发送记录存入数据库
                    SmsSend smssend = new SmsSend();
                    smssend.setReserveId(reserve.getReserveId());
                    smssend.setText(text);
                    smssend.setType("1");
                    smssend.setMobiles(tels);
                    smssend.setSmsNum(total_count);
                    Date date = new Date();
                    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    smssend.setSendTime(df.format(date));
                    smssend.save();
                }
                Map<String, String> xml = new HashMap<String, String>();
                xml.put("return_code", "SUCCESS");
                xml.put("return_msg", "OK");
                renderText(PaymentKit.toXml(xml));
                return;
            }
        }
        renderText("");
    }

    public void success() {
        render("success.html");
    }

    /**
     * 接受短信并回短信
     */
    public void smsReturn() {
        SimpleDateFormat d = new SimpleDateFormat("yyyyMMdd");
        Date date = new Date();
        String sms_reply = getPara("sms_reply");
        String json = URLDecoder.decode(sms_reply, "utf-8");
        JSONObject replyJosn = JSONObject.parseObject(json);
        String tel = replyJosn.getString("mobile");// 信息号码
        String text = replyJosn.getString("text");// 信息内容
        String reserveId = "";
        if (d.format(date).substring(6).equals(text.substring(0, 2))) {
            reserveId = d.format(date).substring(2, 6) + text;
        } else {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.add(Calendar.DAY_OF_MONTH, -1);
            date = calendar.getTime();
            reserveId = d.format(date).substring(2, 8) + text.substring(2);
        }
        // 将商家回复信息存入数据库
        // sms_return
        SmsReturn sms_return = new SmsReturn();
        sms_return.setMobile(tel);
        sms_return.setReserveId(reserveId);
        sms_return.setText(text);
        sms_return.setReturnTime(replyJosn.getString("reply_time"));
        sms_return.save();
        renderText("0");
    }
}
